# res://scripts/BattleManager.gd
# Manages the overall flow of a 3v3 battle.

extends Node

class_name BattleManager

# Reference to the scene's nodes
# @onready var action_bar = $"../UI/ActionBar" # Assuming UI structure - FIXME: This path is incorrect in the current scene setup
@onready var player_characters = [$"../PlayerSide/Char1", $"../PlayerSide/Char2", $"../PlayerSide/Char3"]
@onready var enemy_characters = [$"../EnemySide/CharA", $"../EnemySide/CharB", $"../EnemySide/CharC"]

# Action order list (priority queue simulation)
var action_queue = []

# Reference to the character whose turn it is
var current_active_character: Character = null

# State of the battle
enum BattleState { PRE_BATTLE, PLAYER_TURN, ENEMY_TURN, REACTION_PHASE, BATTLE_END }
var current_state: BattleState = BattleState.PRE_BATTLE

# For reaction phase timing
var reaction_timer: Timer
var target_for_reaction: Character = null

# Called when the node enters the scene tree for the first time.
func _ready():
	# Initialize the battle
	initialize_battle()
	
	# Setup timer for reaction phase
	reaction_timer = Timer.new()
	add_child(reaction_timer)
	reaction_timer.one_shot = true
	reaction_timer.connect("timeout", Callable(self, "_on_reaction_timeout"))

# Initialize the battle state
func initialize_battle():
	print("Initializing battle...")
	current_state = BattleState.PRE_BATTLE
	
	# Set initial HP/SP based on GDD
	for char in player_characters + enemy_characters:
		if char:
			char.current_hp = char.max_hp
			char.current_sp = 50 # As per GDD
			
	# Calculate initial action order
	update_action_queue()
	
	# Trigger start-of-battle passives (simplified)
	for char in action_queue:
		# Example: A passive that boosts ATK for everyone at start
		# char.atk += 5 
		pass
		
	print("Action Order: ", action_queue.map(func(c): return c.character_name))
	
	# Start the battle loop
	current_state = BattleState.PLAYER_TURN
	process_next_turn()

# Update the action queue based on character speed
func update_action_queue():
	action_queue.clear()
	
	# Combine all alive characters
	var all_chars = []
	for char in player_characters + enemy_characters:
		if char and char.current_hp > 0:
			all_chars.append(char)
	
	# Sort by speed (descending) - higher speed acts first
	# In a more complex system, you'd use a proper priority queue or action bar logic
	all_chars.sort_custom(func(a, b): return a.speed > b.speed)
	action_queue = all_chars

# Main battle loop processor
func process_next_turn():
	if check_battle_end_conditions():
		return
		
	update_action_queue()
	
	if action_queue.is_empty():
		print("No characters left to act. This should not happen.")
		return
		
	var next_char: Character = action_queue[0]
	current_active_character = next_char
	
	print("\n--- %s's Turn ---" % next_char.name)
	next_char.on_turn_start()
	
	# Determine if it's player or enemy turn
	if player_characters.has(next_char):
		start_player_turn(next_char)
	elif enemy_characters.has(next_char):
		start_enemy_turn(next_char)

# Start a player character's turn
func start_player_turn(character: Character):
	current_state = BattleState.PLAYER_TURN
	print("It's a PLAYER turn. Please make your decision (in code for now).")
	# In a real game, this would enable UI for player input.
	# For prototype, we'll simulate a decision.
	
	# Simulate player decision: Attack first enemy
	var target = get_first_alive(enemy_characters)
	if target:
		# Simulate standard attack
		var is_defeated = character.perform_action(target, "attack", 0)
		if is_defeated:
			print("%s has been defeated!" % target.character_name)
			# TODO: Handle character defeat (e.g., remove from action queue visually)
	
	end_turn()

# Start an enemy character's turn
func start_enemy_turn(character: Character):
	current_state = BattleState.ENEMY_TURN
	print("It's an ENEMY turn.")
	
	# Simulate enemy AI decision: Attack first player
	var target = get_first_alive(player_characters)
	if target:
		print("%s is about to attack %s." % [character.character_name, target.character_name])
		# Show pre-action indicator (simplified log)
		print("Warning: Enemy attack incoming!")
		
		# Enter reaction phase
		start_reaction_phase(target, character)

# Start the reaction phase for a player character
func start_reaction_phase(target_character: Character, attacker: Character):
	current_state = BattleState.REACTION_PHASE
	target_for_reaction = target_character
	
	print("Entering REACTION PHASE for %s. You have 1.2 seconds to guard!" % target_character.name)
	
	# Start the 1.2s timer for reaction
	reaction_timer.start(1.2) # 1.2 seconds as per GDD
	
	# In a real game, this is where you'd show the guard button and wait for input.
	# For prototype, we'll simulate a random guard decision.
	var guard_decision = randi() % 3 # 0: No guard, 1: Standard guard, 2: Perfect guard
	# Let's simulate a perfect guard sometimes for testing
	if guard_decision == 2:
		_on_guard_button_pressed(true) # Simulate perfect guard
	elif guard_decision == 1:
		_on_guard_button_pressed(false) # Simulate standard guard
	# If 0, do nothing, let the timer expire

# Handle when the reaction timer expires (no guard)
func _on_reaction_timeout():
	if current_state == BattleState.REACTION_PHASE:
		print("Reaction time expired. No guard performed.")
		# Apply full damage
		# This part is a bit tricky in the prototype as damage is applied in perform_action
		# We need to decouple action execution from damage application for reaction phase
		# For simplicity, let's assume the enemy's action was a standard attack
		# and apply a fixed damage. In a real system, the damage value would be pre-calculated.
		var simulated_damage = 25 # Placeholder damage
		target_for_reaction.take_damage(simulated_damage)
		
		end_reaction_phase()
		end_turn()

# Handle guard button press (simulated or real)
func _on_guard_button_pressed(is_perfect: bool = false):
	if current_state != BattleState.REACTION_PHASE:
		print("Guard button pressed outside of reaction phase.")
		return
		
	print("Guard button pressed! Is Perfect: ", is_perfect)
	reaction_timer.stop() # Stop the timer as action is taken
	
	# Apply guarded damage logic
	# Again, simplifying by using a placeholder damage value
	var simulated_damage = 25
	if is_perfect:
		target_for_reaction.receive_attack(simulated_damage, true)
	else:
		target_for_reaction.receive_attack(simulated_damage, false)
		
	end_reaction_phase()
	end_turn()

# End the reaction phase
func end_reaction_phase():
	current_state = BattleState.ENEMY_TURN # Or PLAYER_TURN if it was player's action
	target_for_reaction = null

# End the current character's turn
func end_turn():
	print("%s's turn ended." % current_active_character.name)
	current_active_character = null
	current_state = BattleState.PLAYER_TURN # Reset to a default state
	
	# Continue the battle loop
	process_next_turn()

# Check if the battle has ended (victory/defeat)
func check_battle_end_conditions() -> bool:
	var player_alive = false
	var enemy_alive = false
	
	for char in player_characters:
		if char and char.current_hp > 0:
			player_alive = true
			break
			
	for char in enemy_characters:
		if char and char.current_hp > 0:
			enemy_alive = true
			break
	
	if not player_alive:
		current_state = BattleState.BATTLE_END
		print("\n*** BATTLE LOST ***")
		# TODO: Show defeat screen
		return true
	elif not enemy_alive:
		current_state = BattleState.BATTLE_END
		print("\n*** BATTLE WON ***")
		# TODO: Show victory screen
		return true
		
	return false

# Helper function to get the first alive character from a list
func get_first_alive(char_list) -> Character:
	for char in char_list:
		if char and char.current_hp > 0:
			return char
	return null
